#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#ifndef __COMMON_H__
#define __COMMON_H__
#define TABLE_MAX_PAGE 100
#define COLUMN_USERNAME_SIZE 32
#define COLUMN_EMAIL_SIZE 255

// 数据库中行的结构体
// 创建结构体存放row的信息,包括id，用户名称，以及邮件三个字段
typedef struct
{
    uint32_t id;
    char username[COLUMN_USERNAME_SIZE];
    char email[COLUMN_EMAIL_SIZE];
} Row;

// 定义可以被识别的语句，比如以insert和delete开头的语句
typedef enum
{
    STATEMENT_INSERT, // insert语句
    STATEMENT_SELECT  // select语句
} StatementType;

// sql语句
typedef struct
{
    StatementType type;
    Row row_to_insert; // 只用于insert
} Statement;

/**
 * 定义一个结构体，里面包括接受数据的缓存buffer大小，以及长度，和用户输入的长度
 */
typedef struct
{
    char *buffer;         // 接受数据
    size_t buffer_length; // buffer长度
    size_t input_length;  // 控制台输入的长度
} InputBuffer;

/**
 * @brief  定义枚举类型
 * 用枚举类型来表示命令的成功与不能识别
 * @note   
 * @retval None
 */
typedef enum
{
    MATE_COMMAND_SUCCESS,
    META_COMMAND_UNRECOGNIZED_COMMAND
} MetaCommandResult;

// 定义枚举，用来表示执行是否成功
typedef enum
{
    PERPARE_SUCCESS,                // 表示语法通过
    PERPARE_SYNTAX_ERROR,           // 语法错误(part3)
    PERPARE_UNRECOGNIZED_STATEMENT, // 不支持的语法
    PREPARE_SYNTAX_ERROR,           // 语法错误
    PREPARE_STRING_TOO_LONG,        // 字符串长度超出范围(part4)
    PREPARE_NEGATIVE_ID             // id不能是负数
} PrepareResult;

// 数据库表的结构体
typedef struct
{
    uint32_t num_rows;           // 行数
    void *pages[TABLE_MAX_PAGE]; // 一张表存放的页数
} Table;

typedef enum
{
    EXECUTE_SUCCESS,       // 执行成功
    EXECUTE_DUPLICATE_KEY, // 重复主键
    EXECUTE_TABLE_FULL     // 表已满
} ExecuteResult;

// *******************************-------*************************************
// *******************************公共函数*************************************
// *******************************=======*************************************

/**
 * 初始化结构体InputBuffer中的成员变量
 * @return
 */
InputBuffer *new_input_buffer();

/**
 * 打印控制台的头部
 */
void print_prompt();

/**
 * @brief  读取输入一行的字符串字节
 * @note   
 * @param  **lineptr: 输入字符串的指针
 * @param  *n:        
 * @param  *stream:  输入流
 * @retval 
 */
ssize_t getline(char **lineptr, size_t *n, FILE *stream);

/**
 * @brief  读取输入的字符串数据
 * @note   
 * @param  *input_buffer: 存放输入字符串的结构体指针
 * @retval None
 */
void read_input(InputBuffer *input_buffer);

/**
 * 释放分配给InputBuffer *的内存和buffer中元素各自的结构
 * @param input_buffer
 */
void close_input_buffer(InputBuffer *input_buffer);

// **************************---------------********************************
// *************************|  第 四 部 分  |********************************
// **************************---------------********************************

/**
 * @brief  插入前准备
 * @note   
 * @param  *input_buffer: 输入字符串结构体指针对象
 * @param  *statement:    插入语法
 * @retval 
 */
PrepareResult prepare_insert(InputBuffer *input_buffer, Statement *statement);
#endif
